﻿//===================================================================================
// Copyright (c) Ryan Garrett.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===================================================================================

using System;
using System.Collections.Generic;
using System.Linq;

namespace Caffeine.Core.Test.TestModel
{
    public class ModelForPropertyTestingC : ModelBase
    {
        private readonly ModelProperty<Int32> _intProperty1;
        private readonly ModelProperty<Int32> _intProperty2;
        private readonly ModelProperty<Int32> _intProperty3;
        private readonly ModelProperty<Int32> _intProperty4;
        private readonly ModelProperty<Int32> _intProperty5;
        private readonly ModelProperty<String> _firstNameProperty;
        private readonly ModelProperty<String> _lastNameProperty;
        private readonly ModelProperty<String> _fullNameProperty;
        private readonly ModelProperty<ModelForPropertyTestingC> _child;
        private readonly ModelProperty<ModelForPropertyTestingC> _child2;
        private readonly ModelProperty<ModelForPropertyTestingC> _child3;

        public ModelForPropertyTestingC()
        {
            _intProperty1 = RegisterProperty<Int32>("IntProperty1", ModelBase.StandardBehaviors.RemoveBehavior(ModelPropertyBehaviors.SetsParentIsDirty));
            _intProperty2 = RegisterProperty<Int32>("IntProperty2");
            _intProperty3 = RegisterProperty<Int32>("IntProperty3", null);
            _intProperty4 = RegisterProperty<Int32>("IntProperty4", ModelPropertyBehaviors.SetsIsDirty.AddBehavior(ModelPropertyBehaviors.SetsParentIsDirty));
            _intProperty5 = RegisterProperty<Int32>("IntProperty5", ModelBase.StandardBehaviors.RemoveBehavior(ModelPropertyBehaviors.SetsIsDirty));
            _child = RegisterProperty<ModelForPropertyTestingC>("Child", null);
            _child2 = RegisterProperty<ModelForPropertyTestingC>("Child2", null);
            _child3 = RegisterProperty<ModelForPropertyTestingC>("Child3");
            _firstNameProperty = RegisterProperty<String>("FirstNameProperty");
            _lastNameProperty = RegisterProperty<String>("LastNameProperty");
            _fullNameProperty = RegisterComputedProperty<String, String>
            (
                "FullNameProperty", 
                ComputeFullName, 
                ModelBase.StandardBehaviors.RemoveBehavior(ModelPropertyBehaviors.SetsIsDirty), 
                FirstNameProperty, 
                LastNameProperty
            );
        }

        protected override void OnInitialized()
        {
            base.OnInitialized();
            IntProperty2.ValidationMethod = CheckIsIntProperty2Valid;
        }

        private static void CheckIsIntProperty2Valid(ModelProperty<Int32> property, ref IEnumerable<ValidationError> errors, ref Boolean isValid)
        {
            isValid = property.IsDefault;
        }

        public ModelProperty<Int32> IntProperty1
        {
            get
            {
                return _intProperty1;
            }
        }

        public ModelProperty<Int32> IntProperty2
        {
            get
            {
                return _intProperty2;
            }
        }

        public ModelProperty<Int32> IntProperty3
        {
            get
            {
                return _intProperty3;
            }
        }

        public ModelProperty<Int32> IntProperty4
        {
            get
            {
                return _intProperty4;
            }
        }

        public ModelProperty<Int32> IntProperty5
        {
            get
            {
                return _intProperty5;
            }
        }

        public ModelProperty<String> FirstNameProperty
        {
            get
            {
                return _firstNameProperty;
            }
        }

        public ModelProperty<String> LastNameProperty
        {
            get
            {
                return _lastNameProperty;
            }
        }

        public ModelProperty<String> FullNameProperty
        {
            get
            {
                return _fullNameProperty;
            }
        }

        public ModelProperty<ModelForPropertyTestingC> Child
        {
            get
            {
                return _child;
            }
        }

        public ModelProperty<ModelForPropertyTestingC> Child2
        {
            get
            {
                return _child2;
            }
        }

        public ModelProperty<ModelForPropertyTestingC> Child3
        {
            get
            {
                return _child3;
            }
        }

        public override void Commit()
        {
            base.Commit();
        }

        protected override void OnBeforeParentChanged()
        {
            base.OnBeforeParentChanged();
        }

        protected override void OnParentChanged()
        {
            base.OnParentChanged();
        }

        protected override void OnParentPropertyChanged(ModelScalarPropertyBase parentProperty)
        {
            base.OnParentPropertyChanged(parentProperty);
        }

        protected override void OnAssignedToProperty(ModelScalarPropertyBase parentProperty)
        {
            base.OnAssignedToProperty(parentProperty);
        }

        protected override void OnCommittedToProperty(ModelScalarPropertyBase parentProperty)
        {
            base.OnCommittedToProperty(parentProperty);
        }

        protected override void OnMarkedForRemovalFromProperty(ModelScalarPropertyBase parentProperty)
        {
            base.OnMarkedForRemovalFromProperty(parentProperty);
        }

        protected override void OnRemovedFromParentProperty(ModelScalarPropertyBase parentProperty)
        {
            base.OnRemovedFromParentProperty(parentProperty);
        }

        private static String ComputeFullName(IEnumerable<ModelProperty<String>> properties, String newPropertyValue)
        {
            ModelProperty<String> firstNameProperty = properties.Single(property => property.Name == "FirstNameProperty");
            ModelProperty<String> lastNameProperty = properties.Single(property => property.Name == "LastNameProperty");

            String fullName = String.Empty;

            if (String.IsNullOrEmpty(firstNameProperty.Value) || String.IsNullOrEmpty(lastNameProperty.Value))
            {
                fullName = "(Please enter full name)";
            }
            else
            {
                fullName = String.Format("{1}, {0}", firstNameProperty.Value, lastNameProperty.Value);
            }

            return fullName;
        }
    }
}
